#include "cms_event.h"
#include "cms_log.h"
#include "task_utils.h"
#include "task_module.h"
#include "libmdm.h"
#include "cms_mdm.h"
#include "cms_serviceCmdCode.h"
#include "cmsXml_object.h"

/*-------------------------------------------------------------------
 * Object Code Start
 * ----------------------------------------------------------------*/

const cmsConfigRegData_t task_objectSample = {
    "objSample",
    objectSample_handler,
    CMS_NOTIFY_PRORITY_REALTIME,
    {
        OID_InternetGatewayDevice_Services_example,
        OID_InternetGatewayDevice_Services_example_VPNConnection_i,
        0
    }
};

const cmsConfigRegData_t *objectSample[] = {
    &task_objectSample,
    NULL
};

int cmsTask_regObjectInit_sample(void){
    int ret = -1;
    
    ret = cmsTask_regObjectToCms(objectSample);

    CMS_LOG(LL_INFO, "reg object to cmsTask %s.", (ret == 0) ? "success" : "fail");
    return ret;
}

int objectSample_handler(void  *ptr){
    cms_configChgArg_t *objectChgArg = NULL;
    objChgInfo_t *pObjInfo = NULL;
    cmsXmlCb_t *xmlShmCb = NULL;
    void *object = NULL;
    uint32_t objDepth = 0;
    uint32_t objID = 0;
    uint64_t objIA = 0;
    int idx = 0;
    cmsObj_InternetGatewayDevice_Services_example_t *ex;
    cmsObj_InternetGatewayDevice_Services_example_VPNConnection_i_t *exi;

    if(ptr == NULL){
        /**************************************
         * boot up code here
         *************************************/
        CMS_LOG(LL_PRINT, "boot up:example");
    }else{
        /**************************************
         * object change
         *************************************/
        xmlShmCb = XMLSHMINIT();
        if (xmlShmCb == NULL){
            CMS_LOG(LL_ERROR, "xmlShm init error");
            return -1;
        }
            
        objectChgArg = (cms_configChgArg_t*)ptr;
        while(objectChgArg){
            objDepth = objectChgArg->event->eventCount;
            CMS_LOG(LL_DEBUG, "the depth of this object is %d.", objDepth);

            objID = objectChgArg->event->eventId[objDepth - 1];
            objIA  =  GenerateIA(objectChgArg->event->eventId[objDepth], objectChgArg->event->eventId[objDepth + 1]);
            CMS_LOG(LL_DEBUG, "the changed objId %d, %"PRIx64, objID, objIA);

            pObjInfo = getObjInfoByIA(objID, objIA);
            if(pObjInfo == NULL){
                CMS_LOG(LL_ERROR, "getObjInfoByIA failed!!");
                goto _error;
            }

            switch(objID){
                case OID_InternetGatewayDevice_Services_example:
                    object = cmsXml_GetObjectByOID(xmlShmCb, objID, objIA,  NULL_IF_NOT_EXISTED);
                    if(object != NULL){
                        ex = (cmsObj_InternetGatewayDevice_Services_example_t *)object;
                        printf("===prefix=%s\n", ex->prefix);
                    }
                    break;
                case OID_InternetGatewayDevice_Services_example_VPNConnection_i:
                    idx = pObjInfo->objIndexValue[pObjInfo->indexDepth - 1];
                    object = cmsXml_GetObjectByOID(xmlShmCb, objID, objIA,  NULL_IF_NOT_EXISTED);
                    if(object != NULL){
                        exi = (cmsObj_InternetGatewayDevice_Services_example_VPNConnection_i_t *)object;

                        if(objectChgArg->objAction == CMS_OBJ_ADD){
                            printf("===ADD idx=%d Enable=%d Type=%s\n", idx, exi->Enable, exi->Type);
                        }else if(objectChgArg->objAction == CMS_OBJ_SET){
                            printf("===SET idx=%d Enable=%d Type=%s\n", idx, exi->Enable, exi->Type);
                        }

                    }else{
                        CMS_LOG(LL_DEBUG, "object %d has been deleted.", idx);
                        if(objectChgArg->oldObjData == NULL){
                            CMS_LOG(LL_ERROR, "oldObjData is NULL!");
                            goto _error;
                        }
                        exi = (cmsObj_InternetGatewayDevice_Services_example_VPNConnection_i_t *)objectChgArg->oldObjData;
                        printf("===DEL idx=%d Enable=%d Type=%s\n", idx, exi->Enable, exi->Type);

                    }
                    break;
                default:
                    break;
            }
                
            objectChgArg = objectChgArg->next;
        }

        XMLSHMDEINIT(xmlShmCb);
    }

    return 0;

_error:
    XMLSHMDEINIT(xmlShmCb);
    return -1;
}
/*-------------------------------------------------------------------
 * Object Code End
 * ----------------------------------------------------------------*/


/*-------------------------------------------------------------------
 * Event Handle Code Start
 * ----------------------------------------------------------------*/
int eventSample_handler(uint32_t eventId, uint32_t typeSizeOfValue, void *eventContent);
int cmdSample_handler(uint32_t serviceCode, value_t *arg);

/*event reg sample*/
const cmsEventRegData_t task_eventSample = {
    "eSample",
    eventSample_handler,
    CMS_NOTIFY_PRORITY_LOWEST,
    {
        CMS_EVENT_SAMPLE_1,
        CMS_EVENT_SAMPLE_2,
        CMS_EVENT_SAMPLE_3,
        CMS_EVENT_SAMPLE_4,
        0
    }
    
};

const cmsEventRegData_t *eventSample[] = {
    &task_eventSample,
    NULL
};

/*cmd reg sample*/
const cmsTask_cmdServiceRegData_t task_cmdSample = {
    "cmdSample",
    cmdSample_handler,
    CMS_NOTIFY_PRORITY_REALTIME,
    {
        CMS_SERVICE_TEST,
        0
    }
    
};

const cmsTask_cmdServiceRegData_t *cmdSample[] = {
    &task_cmdSample,
    NULL
};

/*event reg sample func*/
int cmsTask_regEventInit_sample(void){
    int ret = -1;
    
    ret = cmsTask_regEventToCms(eventSample);
    CMS_LOG(LL_INFO, "reg event to cmsTask %s.\n", (ret == 0) ? "success" : "fail");

    ret = cmsTask_regCmdServiceToCms(cmdSample);
    CMS_LOG(LL_INFO, "reg cmd to cmsTask %s.\n", (ret == 0) ? "success" : "fail");
    
    return ret;
}

int eventSample_handler(uint32_t eventId, uint32_t typeSizeOfValue, void *eventContent){
    CMS_LOG(LL_DEBUG, "Entrance\n");

    switch(eventId){
        case CMS_EVENT_SAMPLE_1:
            CMS_LOG(LL_INFO, "event sample1 test, value type 0x%x.\n",typeSizeOfValue);
            if(typeSizeOfValue == PARAMETER_TYPE_UINT8){
                CMS_LOG(LL_INFO, "event value is %d", *(uint8_t *)eventContent);
            }else if(typeSizeOfValue == PARAMETER_TYPE_UINT16){
                CMS_LOG(LL_INFO, "event value is %d", *(uint16_t *)eventContent);
            }else if(typeSizeOfValue == PARAMETER_TYPE_UINT32){
                CMS_LOG(LL_INFO, "event value is %d", *(uint32_t *)eventContent);
            }else if(typeSizeOfValue == PARAMETER_TYPE_STRING){
                CMS_LOG(LL_INFO, "event value is %s", (char *)eventContent);
            }
            break;
        case CMS_EVENT_SAMPLE_2:
            CMS_LOG(LL_INFO, "event sample2 test, value type 0x%x.\n", typeSizeOfValue);
            if(typeSizeOfValue == PARAMETER_TYPE_UINT8){
                CMS_LOG(LL_INFO, "event value is %d", *(uint8_t *)eventContent);
            }else if(typeSizeOfValue == PARAMETER_TYPE_UINT16){
                CMS_LOG(LL_INFO, "event value is %d", *(uint16_t *)eventContent);
            }else if(typeSizeOfValue == PARAMETER_TYPE_UINT32){
                CMS_LOG(LL_INFO, "event value is %d", *(uint32_t *)eventContent);
            }else if(typeSizeOfValue == PARAMETER_TYPE_STRING){
                CMS_LOG(LL_INFO, "event value is %s", (char *)eventContent);
            }
            break;
        case CMS_EVENT_SAMPLE_3:
            CMS_LOG(LL_INFO, "event sample3 test, value type 0x%x.\n",typeSizeOfValue);
            if(typeSizeOfValue == PARAMETER_TYPE_UINT8){
                CMS_LOG(LL_INFO, "event value is %d", *(uint8_t *)eventContent);
            }else if(typeSizeOfValue == PARAMETER_TYPE_UINT16){
                CMS_LOG(LL_INFO, "event value is %d", *(uint16_t *)eventContent);
            }else if(typeSizeOfValue == PARAMETER_TYPE_UINT32){
                CMS_LOG(LL_INFO, "event value is %d", *(uint32_t *)eventContent);
            }else if(typeSizeOfValue == PARAMETER_TYPE_STRING){
                CMS_LOG(LL_INFO, "event value is %s", (char *)eventContent);
            }
            break;
        case CMS_EVENT_SAMPLE_4:
            CMS_LOG(LL_INFO, "event sample4 test, value type 0x%x.\n", typeSizeOfValue);
            if(typeSizeOfValue == PARAMETER_TYPE_UINT8){
                CMS_LOG(LL_INFO, "event value is %d", *(uint8_t *)eventContent);
            }else if(typeSizeOfValue == PARAMETER_TYPE_UINT16){
                CMS_LOG(LL_INFO, "event value is %d", *(uint16_t *)eventContent);
            }else if(typeSizeOfValue == PARAMETER_TYPE_UINT32){
                CMS_LOG(LL_INFO, "event value is %d", *(uint32_t *)eventContent);
            }else if(typeSizeOfValue == PARAMETER_TYPE_STRING){
                CMS_LOG(LL_INFO, "event value is %s", (char *)eventContent);
            }
            break;
        default:
            CMS_LOG(LL_ERROR, "unkonw event %d", eventId);
            return -1;
            
    }

    CMS_LOG(LL_DEBUG, "Exit\n");
    return 0;
}

/*cmd reg sample func*/
int cmdSample_handler(uint32_t serviceCode, value_t *arg){
    CMS_LOG(LL_DEBUG, "Entrance\n");
    uint8_t *value = arg->value;

    switch(serviceCode){
        case CMS_SERVICE_TEST:
            CMS_LOG(LL_INFO, "service cmd code.\n");
            if(arg->typeSizeOfValue == PARAMETER_TYPE_UINT8){
                CMS_LOG(LL_INFO, "service value is %d", *(uint8_t *)value);
            }else if(arg->typeSizeOfValue == PARAMETER_TYPE_UINT16){
                CMS_LOG(LL_INFO, "service value is %d", *(uint16_t *)value);
            }else if(arg->typeSizeOfValue == PARAMETER_TYPE_UINT32){
                CMS_LOG(LL_INFO, "service value is %d", *(uint32_t *)value);
            }else if(arg->typeSizeOfValue == PARAMETER_TYPE_STRING){
                CMS_LOG(LL_INFO, "service value is %s", value);
            }
            
            break;
        default:
            CMS_LOG(LL_ERROR, "unkonw cmd %d", serviceCode);
            return -1;
            
    }

    CMS_LOG(LL_DEBUG, "Exit\n");
    return 0;
}
/*-------------------------------------------------------------------
 * Event Handle Code End
 * ----------------------------------------------------------------*/




/*-------------------------------------------------------------------
 * Module Init Function
 * ----------------------------------------------------------------*/
int cmsTask_regInit_sample(void)
{
    cmsTask_regObjectInit_sample();
    cmsTask_regEventInit_sample();

    return 0;
}
